#include <stdio.h>
#include <stdlib.h>
#include <omp.h>

omp_lock_t* new_lock()
{
    omp_lock_t *lock_ptr;

    #pragma omp single copyprivate(lock_ptr)
    {
        lock_ptr = (omp_lock_t *)malloc(sizeof(omp_lock_t));
        omp_init_lock(lock_ptr);
    }

    return lock_ptr;
}

int main()
{
    omp_lock_t *lock;
    int counter = 0;
    printf("OpenMP Lock初始化完毕\n");

    #pragma omp parallel num_threads(4) shared(counter)
    {
        int tid = omp_get_thread_num();
        int t;

        // 获取锁 (新线程获取锁用到的初始对象)
        lock = new_lock();
        printf("线程 %d 获取了初始锁: %p\n", tid, (void*)lock);

        // 使用锁保护计数区
        for (t = 0; t < 3; t++) {
            omp_set_lock(lock);
            // 临界区 - 递增计数器
            counter++;
            printf("线程 %d: 递增计数器到 %d\n", tid, counter);
            // 在实际应用中可用的sleep，此处省略以简化
            // 释放锁
            omp_unset_lock(lock);
        }

        // 使用barrier确保所有线程完成后对锁的使用
        #pragma omp barrier

        // 只有一个线程负责释放锁
        #pragma omp single
        {
            omp_destroy_lock(lock);
            free(lock);
            printf("锁已被销毁并释放内存\n");
        }
    }

    printf("最终计数器值: %d (预期值: 12)\n", counter);

    return 0;
}